package rules

import (
	"fmt"
	"strings"

	"ddl_checker/internal/parser"
)

// DatabaseComplianceRule 数据库规范检查规则
type DatabaseComplianceRule struct{}

// Name 规则名称
func (r *DatabaseComplianceRule) Name() string {
	return "DDL验证结果"
}

// Check 执行检查
func (r *DatabaseComplianceRule) Check(data DDLCheckData) CheckResult {
	result := CheckResult{
		Status:  StatusPassed,
		Details: make([]string, 0),
	}

	// 检查DDL脚本规范
	if strings.TrimSpace(data.Script) != "" {
		ddlDetails := r.checkDDLCompliance(data.Script, data.Schema, data.Table)
		result.Details = append(result.Details, ddlDetails...)
		if !r.allPassed(ddlDetails) {
			result.Status = StatusFailed
		}
	} else {
		result.Details = append(result.Details, "⚠️ 未提供DDL脚本，跳过DDL验证")
		result.Status = StatusSkipped
	}

	return result
}

// checkDDLCompliance 检查DDL脚本规范
func (r *DatabaseComplianceRule) checkDDLCompliance(script, schema, table string) []string {
	details := []string{"### DDL脚本规范检查"}

	// 使用HybridAnalyzer进行SQL语法验证
	hybridAnalyzer := parser.NewHybridAnalyzer()

	// 解析SQL语句
	statements, err := hybridAnalyzer.ParseBatchDDL(script, ";")
	if err != nil {
		details = append(details, fmt.Sprintf("❌ DDL语法验证失败: %v", err))
	} else if len(statements) == 0 {
		details = append(details, "❌ 未找到有效的SQL语句")
	} else {
		// 检查每条语句的语法正确性
		allValid := true
		var validDDLStatements int

		for i, stmt := range statements {
			if !stmt.IsValid {
				details = append(details, fmt.Sprintf("❌ 语句%d语法错误: %s", i+1, stmt.Error))
				allValid = false
			} else if stmt.StatementType.IsDDL() {
				validDDLStatements++
				details = append(details, fmt.Sprintf("✅ 语句%d语法正确 (%s, 使用%s解析器)", i+1, stmt.StatementType.String(), stmt.ParserUsed.String()))
			} else {
				details = append(details, fmt.Sprintf("⚠️ 语句%d不是DDL语句 (%s)", i+1, stmt.StatementType.String()))
			}
		}

		if allValid && validDDLStatements > 0 {
			details = append(details, fmt.Sprintf("✅ DDL脚本语法正确，共解析出%d条有效DDL语句", validDDLStatements))
		} else if validDDLStatements == 0 {
			details = append(details, "❌ DDL脚本必须包含CREATE、ALTER或DROP语句")
		}
	}

	// 检查是否使用schema.table格式（仅在语法正确时检查）
	expectedFormat := fmt.Sprintf("%s.%s", schema, table)
	if strings.Contains(script, expectedFormat) {
		details = append(details, "✅ DDL脚本正确使用了schema.table格式")
	} else if schema != "" && table != "" {
		details = append(details, fmt.Sprintf("❌ DDL脚本应使用%s格式引用表", expectedFormat))
	} else {
		details = append(details, "⚠️ 未提供schema或table信息，跳过格式检查")
	}

	details = append(details, "")
	return details
}

// checkRollbackCompliance 检查回滚脚本规范
func (r *DatabaseComplianceRule) checkRollbackCompliance(script, schema, table string) []string {
	details := []string{"### 回滚脚本规范检查"}

	// 使用HybridAnalyzer进行SQL语法验证
	hybridAnalyzer := parser.NewHybridAnalyzer()

	// 解析SQL语句
	statements, err := hybridAnalyzer.ParseBatchDDL(script, ";")
	if err != nil {
		details = append(details, fmt.Sprintf("❌ 回滚脚本语法验证失败: %v", err))
	} else if len(statements) == 0 {
		details = append(details, "❌ 未找到有效的回滚SQL语句")
	} else {
		// 检查每条语句的语法正确性
		allValid := true
		var validDDLStatements int

		for i, stmt := range statements {
			if !stmt.IsValid {
				details = append(details, fmt.Sprintf("❌ 回滚语句%d语法错误: %s", i+1, stmt.Error))
				allValid = false
			} else if stmt.StatementType.IsDDL() {
				validDDLStatements++
				details = append(details, fmt.Sprintf("✅ 回滚语句%d语法正确 (%s, 使用%s解析器)", i+1, stmt.StatementType.String(), stmt.ParserUsed.String()))
			} else {
				details = append(details, fmt.Sprintf("⚠️ 回滚语句%d不是DDL语句 (%s)", i+1, stmt.StatementType.String()))
			}
		}

		if allValid && validDDLStatements > 0 {
			details = append(details, fmt.Sprintf("✅ 回滚脚本语法正确，共解析出%d条有效DDL语句", validDDLStatements))
		} else if validDDLStatements == 0 {
			details = append(details, "❌ 回滚脚本应包含DROP、ALTER或CREATE语句")
		}
	}

	// 检查是否使用schema.table格式（仅在语法正确时检查）
	expectedFormat := fmt.Sprintf("%s.%s", schema, table)
	if strings.Contains(script, expectedFormat) {
		details = append(details, "✅ 回滚脚本正确使用了schema.table格式")
	} else if schema != "" && table != "" {
		details = append(details, fmt.Sprintf("❌ 回滚脚本应使用%s格式引用表", expectedFormat))
	} else {
		details = append(details, "⚠️ 未提供schema或table信息，跳过格式检查")
	}

	details = append(details, "")
	return details
}

// allPassed 检查所有检查项是否都通过
func (r *DatabaseComplianceRule) allPassed(details []string) bool {
	for _, detail := range details {
		if strings.Contains(detail, "❌") {
			return false
		}
	}
	return true
}
